package io.gitee.zhangbinhub.admin.workflow.controller.openinner

import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.admin.common.api.CommonPath
import io.gitee.zhangbinhub.admin.common.api.WorkFlowApi
import io.gitee.zhangbinhub.admin.common.base.BaseController
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.resource.server.po.ProcessHandlingPo
import io.gitee.zhangbinhub.admin.resource.server.po.ProcessStartPo
import io.gitee.zhangbinhub.admin.resource.server.po.ProcessTerminationPo
import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessInstanceVo
import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessTaskVo
import io.gitee.zhangbinhub.admin.workflow.service.WorkFlowService
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.Body
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Mapping
import org.noear.solon.annotation.Path
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("工作流引擎（内部开放接口）")
open class OpenInnerWorkFlowController(
    private val logAdapter: LogAdapter,
    private val workFlowService: WorkFlowService
) : BaseController() {
    @ApiOperation("获取流程任务信息")
    @Mapping(
        method = [MethodType.GET],
        value = CommonPath.openInnerBasePath + WorkFlowApi.task + "/{taskId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun queryTaskInfo(
        @ApiParam(name = "流程任务ID", required = true)
        @Path(name = "taskId") taskId: Long
    ): ProcessTaskVo = workFlowService.findTaskByIdOpen(taskId)

    @ApiOperation("启动流程")
    @Mapping(
        method = [MethodType.PUT],
        value = CommonPath.openInnerBasePath + WorkFlowApi.start,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun start(@Body @Validated processStartPo: ProcessStartPo): InfoVo =
        InfoVo(message = workFlowService.startFlow(processStartPo).id.toString())

    @ApiOperation("启动流程")
    @Mapping(
        method = [MethodType.PUT],
        value = CommonPath.openInnerBasePath + WorkFlowApi.start + "/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun startByUser(
        @Path(name = "userId") userId: String,
        @Body @Validated processStartPo: ProcessStartPo
    ): InfoVo =
        InfoVo(message = workFlowService.startFlow(processStartPo, userId).id.toString())

    @ApiOperation("流程处理")
    @Mapping(
        method = [MethodType.POST],
        value = CommonPath.openInnerBasePath + WorkFlowApi.process + "/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun processByUser(
        @Path(name = "userId") userId: String,
        @Body @Validated processHandlingPo: ProcessHandlingPo
    ): InfoVo = workFlowService.skip(processHandlingPo, userId).let {
        InfoVo(message = "流程处理完成")
    }

    @ApiOperation("查询待办任务")
    @Mapping(
        method = [MethodType.GET],
        value = CommonPath.openInnerBasePath + WorkFlowApi.pending + "/{processInstanceId}/{userId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun pendingByUser(
        @Path(name = "processInstanceId") processInstanceId: Long,
        @Path(name = "userId") userId: String
    ): List<ProcessTaskVo> = workFlowService.findTaskList(processInstanceId, userId)

    @ApiOperation("流程强制结束")
    @Mapping(
        method = [MethodType.DELETE],
        value = CommonPath.openInnerBasePath + WorkFlowApi.termination,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun termination(@Body @Validated processTerminationPo: ProcessTerminationPo): InfoVo =
        workFlowService.findProcessInstance(processTerminationPo.processInstanceId!!).let { instance ->
            if (instance.finished) {
                logAdapter.warn("流程已结束，无法再次终止该流程！")
            }
            workFlowService.terminationFlow(processTerminationPo).let {
                InfoVo(message = "强制结束流程实例成功")
            }
        }

    @ApiOperation("获取流程实例")
    @Mapping(
        method = [MethodType.GET],
        value = CommonPath.openInnerBasePath + WorkFlowApi.instance + "/{processInstanceId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun queryInstance(
        @ApiParam(name = "流程实例id", required = true)
        @Path(name = "processInstanceId")
        processInstanceId: Long
    ): ProcessInstanceVo = workFlowService.findProcessInstance(processInstanceId)
}
